package com.jrx.anytxn.transaction.job.autoPayment.step;

import com.jrx.anytxn.common.uitl.StringUtils;
import com.jrx.anytxn.customer.constant.BankCardConstant;
import com.jrx.anytxn.customer.dto.customer.CustomerRes;
import com.jrx.anytxn.customer.entity.CmCustomerBankcardInfo;
import com.jrx.anytxn.customer.entity.CmCustomerFirstLevel;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerBankcardInfoMapper;
import com.jrx.anytxn.customer.service.ICustomerService;
import com.jrx.anytxn.param.entity.PrAutoPaymentTable;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.entity.PrProductTable;
import com.jrx.anytxn.param.mapper.ext.ExtPrAutoPaymentTableMapper;
import com.jrx.anytxn.param.service.product.IProductTableService;
import com.jrx.anytxn.param.service.system.IBtBatchStatusService;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import com.jrx.anytxn.param.utils.BizTypeProducts;
import com.jrx.anytxn.transaction.bean.DebtBean;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.AmLoanAccountInfo;
import com.jrx.anytxn.transaction.entity.BtAutoPaymentList;
import com.jrx.anytxn.transaction.entity.TlPaymentLog;
import com.jrx.anytxn.transaction.entity.TlPaymentMapping;
import com.jrx.anytxn.transaction.job.autoPayment.bean.PaymentLogBean;
import com.jrx.anytxn.transaction.mapper.ext.ExtAmLoanAccountInfoMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtTlPaymentLogMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtTlPaymentMappingMapper;
import com.jrx.anytxn.transaction.service.ICustBatchService;
import com.jrx.anytxn.transaction.service.IPaymentLogService;
import com.jrx.anytxn.transaction.service.impl.DebtCalculationServiceImpl;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Service
public class AutoPaymentPreProcessor implements ItemProcessor<BtAutoPaymentList, PaymentLogBean> {

    private Logger logger = LoggerFactory.getLogger(AutoPaymentPreCustomerProcessor.class);

    @Autowired
    private IOrganizationTableService organizationTableService;

    @Resource
    private ExtCmCustomerBankcardInfoMapper extCmCustomerBankcardInfoMapper;

    @Resource
    private ExtAmLoanAccountInfoMapper extAmLoanAccountInfoMapper;

    @Resource
    private ExtTlPaymentLogMapper extTlPaymentLogMapper;

    @Resource
    private ExtTlPaymentMappingMapper extTlPaymentMappingMapper;

    @Autowired
    private DebtCalculationServiceImpl debtCalculationService;

    @Autowired
    private IPaymentLogService paymentLogService;

    @Autowired
    private ICustomerService customerService;

    @Autowired
    private IProductTableService productTableService;

    @Autowired
    private IBtBatchStatusService btBatchStatusService;

    @Autowired
    private ICustBatchService custBatchService;

    @Resource
    private ExtPrAutoPaymentTableMapper extPrAutoPaymentTableMapper;


    @Override
    public PaymentLogBean process(BtAutoPaymentList item) throws Exception {
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(TransBizConstant.DEFAULT_ORG_ID);
        Date businessDate = org.getNextProcessingDate();

        //判断是第几次批扣
        int autoPaymentType = btBatchStatusService.countByJobNameAndBusiDateAndTenantId(
                TransBizConstant.AUTO_PAYMENT,businessDate,item.getTenantId());
        String autoPayentType = autoPaymentType+"";

        //只有第一次批扣需要判断客户是否需要账户处理
        if("1".equals(autoPayentType)){
            //查询客户一级信息
            CmCustomerFirstLevel firstLevel = customerService.getFirstLevelByCondition(item.getCustomerId(),TransBizConstant.DEFAULT_ORG_ID,item.getTenantId());
            if(businessDate.compareTo(firstLevel.getNextProcessingDate()) != 0){
                custBatchService.dealCustBatch(item.getCustomerId(), TransBizConstant.DEFAULT_ORG_ID, item.getTenantId());

            }
        }

        //查询客户是否有默认还款卡
        CmCustomerBankcardInfo condition = new CmCustomerBankcardInfo();
        condition.setCustomerId(item.getCustomerId());
        condition.setChannel(item.getChannel());
        condition.setDefaultPayFlag(TransBizConstant.Y_FLAG);
        List<CmCustomerBankcardInfo> bankcardInfoList = extCmCustomerBankcardInfoMapper.selectByCondition(condition);

        if(CollectionUtils.isEmpty(bankcardInfoList)){//不存在默认还款卡
            return  null;
        }

        PaymentLogBean paymentLogBean = new PaymentLogBean();
        List<PrAutoPaymentTable> tableList = extPrAutoPaymentTableMapper.selectByAutoPaymentFlag(TransBizConstant.YES_FLAG);
        List<String> statusList = Arrays.asList(TransBizConstant.LOAN_STATUS_1,TransBizConstant.LOAN_STATUS_2);
        for(PrAutoPaymentTable prAutoPaymentTable : tableList){
            List<String> productIds = new ArrayList<>(Arrays.asList(prAutoPaymentTable.getProductId().split(",")));
            //查询客户正常状态贷款账户列表
            List<AmLoanAccountInfo> accountInfos =
                    extAmLoanAccountInfoMapper.selectByCustAndChannelAndStatusAndProductId(item.getCustomerId(),item.getChannel(),
                            item.getTenantId(),statusList,productIds);
            //订单列表为空
            if(CollectionUtils.isEmpty(accountInfos)){
                continue;
            }

            //筛选符合条件的订单 排除掉核销的订单
            Predicate<AmLoanAccountInfo> getOnDue = loan -> TransBizConstant.LOAN_STATUS_1.equals(loan.getAccountStatus())
                    && loan.getNextPaymentDate().compareTo(businessDate) == 0 && !loan.getChargeoffFlag().equals(TransBizConstant.YES_FLAG);
            Predicate<AmLoanAccountInfo> getOverDue = loan -> TransBizConstant.LOAN_STATUS_2.equals(loan.getAccountStatus())
                    && !loan.getChargeoffFlag().equals(TransBizConstant.YES_FLAG);
            List<AmLoanAccountInfo> newLoanAcctList = accountInfos.stream()
                    .filter(getOnDue.or(getOverDue)).collect(Collectors.toList());

            //若验证后的订单列表不为空
            if(CollectionUtils.isEmpty(newLoanAcctList)){
                continue;
            }

            //查询客戶下处理中的还款流水
            List<String> sumStatusList = Arrays.asList(TransBizConstant.PAYMENT_LOG_SUM_STATUS_O,
                    TransBizConstant.PAYMENT_LOG_SUM_STATUS_T, TransBizConstant.PAYMENT_LOG_SUM_STATUS_D);
            List<TlPaymentLog> tlPaymentLogList =
                    extTlPaymentLogMapper.selectListBySumStatusForBatch(item.getCustomerId(),
                            item.getChannel(),sumStatusList);
            //还款流水不空 与订单匹配
            if(CollectionUtils.isNotEmpty(tlPaymentLogList)){
                List<String> seqNoList = tlPaymentLogList.stream().map(TlPaymentLog::getSeqNo).collect(Collectors.toList());
                //获取还款流水对应的订单信息
                List<String> loanIdList = extTlPaymentMappingMapper.selectBySeqNoListForBatch(seqNoList);
                //剔除正在还款中的数据
                newLoanAcctList.removeIf(amLoanAccountInfo -> loanIdList.contains(amLoanAccountInfo.getLoanId()));
            }
            //若验证后的订单列表不为空
            if(CollectionUtils.isEmpty(newLoanAcctList)){
                continue;
            }

            //查询客户信息
            CustomerRes customer = customerService.getCustomerByChannelAndCustomerIdAndTensnId(item.getChannel(),
                    item.getCustomerId(),item.getTenantId());

            //查询产品信息
            PrProductTable product =
                    productTableService.findProByProIdAndOrgId(newLoanAcctList.get(0).getProductId(),
                            org.getOrganizationId(),item.getTenantId());

            String antoPayType = "";

            //判断本次批扣类型
            String type = prAutoPaymentTable.getAutoPaymentType();
            if(type.contains(",")){
                String[] autoPaymentTyps = type.trim().split(",");
                antoPayType = autoPaymentTyps[autoPaymentType - 1];
            }else{
                if(autoPaymentType == 1){
                    antoPayType = type.trim();
                }
            }
            //如果未获取到本次批扣类型直接退出
            if(StringUtils.isBlank(antoPayType)){
                logger.info("未匹配到本次批量扣款方式");
                continue;
            }

            //按订单时间先后顺序排序
            newLoanAcctList = newLoanAcctList.stream().sorted(Comparator.comparing(AmLoanAccountInfo::getCreateTime)).collect(Collectors.toList());

            String paymenType = antoPayType.substring(0,1);//C 按客户扣款 L 按订单扣款
            String fullPayFlah = antoPayType.substring(1,2);//F 足额扣款 N 非足额扣款

            if(TransBizConstant.AUTO_PAYMRNY_TYPE_C.equals(paymenType)){
                //按照客户扣款
                //构建还款流水
                TlPaymentLog tlPaymentLog =
                        paymentLogService.buildTlPaymentLog(TransBizConstant.REPAYMENT_TYPE_AUTO,
                                bankcardInfoList.get(0), customer, BigDecimal.ZERO, businessDate, product, null);
                tlPaymentLog.setAutoPaymentType(autoPayentType);
                if(TransBizConstant.AUTO_PAYMRNY_TYPE_F.equals(fullPayFlah)){
                    tlPaymentLog.setIsFullPay(TransBizConstant.YES_FLAG);
                }else if(TransBizConstant.AUTO_PAYMRNY_TYPE_N.equals(fullPayFlah)){
                    tlPaymentLog.setIsFullPay(TransBizConstant.NO_FLAG);
                }
                //还款流水与订单映射信息
                List<TlPaymentMapping> tlPaymentMappingList = new ArrayList<>(newLoanAcctList.size());

                //总欠款
                BigDecimal totalDebt = BigDecimal.ZERO;
                //遍历订单计算欠款
                for (AmLoanAccountInfo amLoanAccountInfo : newLoanAcctList) {
                    //计算欠款
                    DebtBean debtBean = debtCalculationService.getBalance(amLoanAccountInfo,businessDate,null, true,true,
                            null);
                    //没有欠款 跳过
                    if(debtBean.getTotalAmount().compareTo(BigDecimal.ZERO)<1){
                        continue;
                    }
                    totalDebt = totalDebt.add(debtBean.getTotalAmount());
                    //构建还款流水与订单映射
                    TlPaymentMapping tlPaymentMapping = paymentLogService.buildTlPaymentMapping(item.getCustomerId(),
                            tlPaymentLog.getSeqNo(),amLoanAccountInfo.getLoanId(),item.getTenantId());
                    tlPaymentMappingList.add(tlPaymentMapping);

                }
                if(totalDebt.compareTo(BigDecimal.ZERO)<=0){//若存在欠款 返回信息
                   continue;
                }

                //还款流水信息
                // @author yhy @date 2023/04/26 获取上次批扣失败客户本次批扣金额
                tlPaymentLog = paymentLogService.getAutoPaymentAmount(prAutoPaymentTable, autoPaymentType, item, totalDebt, businessDate, tlPaymentLog);
                tlPaymentLog.setChargeType(TransBizConstant.PAYMENT_LOG_CHARGE_TYPE_1);
                tlPaymentLog.setDescription(TransBizConstant.REPAYMENT_TYPE_AUTO_CUST_NAME);//交易说明	　
                paymentLogBean.addPaymentLog(tlPaymentLog);
                paymentLogBean.addPaymentMapping(tlPaymentMappingList);
            }else if(TransBizConstant.AUTO_PAYMRNY_TYPE_L.equals(paymenType)){
                //按照订单扣款
                //还款流水列表
                List<TlPaymentLog> savePaymentLogList = new ArrayList<>(newLoanAcctList.size());
                //还款流水与订单映射信息
                List<TlPaymentMapping> tlPaymentMappingList = new ArrayList<>(newLoanAcctList.size());

                //遍历订单计算欠款
                for (AmLoanAccountInfo amLoanAccountInfo : newLoanAcctList) {
                    //计算欠款
                    DebtBean debtBean = debtCalculationService.getBalance(amLoanAccountInfo,businessDate,null, true,true,
                            null);
                    //总欠款
                    BigDecimal totalDebt = debtBean.getTotalAmount();
                    if(totalDebt.compareTo(BigDecimal.ZERO)<=0){
                        continue;
                    }

                    //构建还款流水
                    TlPaymentLog tlPaymentLog =
                            paymentLogService.buildTlPaymentLog(TransBizConstant.REPAYMENT_TYPE_AUTO,
                                    bankcardInfoList.get(0), customer,totalDebt,businessDate,product,null);
                    tlPaymentLog.setDescription(TransBizConstant.REPAYMENT_TYPE_AUTO_ORDER_NAME);//交易说明	　
                    tlPaymentLog.setAutoPaymentType(autoPayentType);
                    if(TransBizConstant.AUTO_PAYMRNY_TYPE_F.equals(fullPayFlah)){
                        tlPaymentLog.setIsFullPay(TransBizConstant.YES_FLAG);
                    }else if(TransBizConstant.AUTO_PAYMRNY_TYPE_N.equals(fullPayFlah)){
                        tlPaymentLog.setIsFullPay(TransBizConstant.NO_FLAG);
                    }
                    // @author yhy @date 2023/04/26 获取上次批扣失败客户本次批扣金额
                    tlPaymentLog = paymentLogService.getAutoPaymentAmount(prAutoPaymentTable, autoPaymentType, item, totalDebt, businessDate, tlPaymentLog);
                    savePaymentLogList.add(tlPaymentLog);

                    //构建还款流水与订单映射
                    TlPaymentMapping tlPaymentMapping = paymentLogService.buildTlPaymentMapping(item.getCustomerId(),
                            tlPaymentLog.getSeqNo(),amLoanAccountInfo.getLoanId(),item.getTenantId());
                    tlPaymentMappingList.add(tlPaymentMapping);

                }
                //判断是否有还款流水
                if(CollectionUtils.isNotEmpty(savePaymentLogList)){//有还款流水 返回信息
                    //还款流水信息
                    paymentLogBean.addPaymentLogList(savePaymentLogList);
                    paymentLogBean.addPaymentMapping(tlPaymentMappingList);
                }
            }
        }

        return paymentLogBean;
    }
}
